package com.bookshop.logic;

import java.rmi.RemoteException;
import java.util.ArrayList;

import com.bookshop.book.logic.Book;
import com.bookshop.order.logic.Order;
import com.bookshop.order.state.OrderState;
import com.bookshop.promotion.logic.DiscountCoupons;
import com.bookshop.promotion.logic.EqualCoupons;
import com.bookshop.promotion.logic.PromotionItem;
import com.bookshop.rmi.Stub;
import com.bookshop.ui.admin.AdminHomePage;
import com.bookshop.ui.admin.AdminNavigater;
import com.bookshop.ui.component.UIConstants;
import com.bookshop.ui.customer.CartPage;
import com.bookshop.ui.customer.CollectionPage;
import com.bookshop.ui.customer.CustomerHomePage;
import com.bookshop.ui.customer.CustomerNavigater;
import com.bookshop.ui.customer.EndBillPanel;
import com.bookshop.ui.customer.OrderPage;
import com.bookshop.ui.customer.PersonalInfoPage;
import com.bookshop.ui.generalManager.GeneralManagerNavigater;
import com.bookshop.ui.generalManager.PromotionSettingPage;
import com.bookshop.ui.generalManager.SendCouponsPage;
import com.bookshop.ui.login.RegisterPanel;
import com.bookshop.ui.marketManager.BookManagePage;
import com.bookshop.ui.marketManager.CustomerManagePage;
import com.bookshop.ui.marketManager.CustomerManagePage.InvolvedData;
import com.bookshop.ui.marketManager.MarketManagerNavigater;
import com.bookshop.ui.marketManager.OrderManagePage;
import com.bookshop.user.identify.UserIdentity;
import com.bookshop.user.logic.CustomerInfo;
import com.bookshop.vo.CustomerVO;
import com.bookshop.vo.LoginVO;
import com.bookshop.vo.OrderVO;
import com.bookshop.vo.OrdersVO;
import com.bookshop.vo.PromotionConfigVO;
import com.bookshop.vo.PromotionItemVO;
import com.bookshop.vo.RegisterVO;
import com.bookshop.vo.SaleVO;
import com.bookshop.vo.SendCouponVO;
import com.bookshop.vo.UserVO;

public class RemoteServiceAdapter {
	public static CartBuf sCartBuf = new CartBuf();

	public static void resetCartBuf() {
		sCartBuf = new CartBuf();
	}

	protected RemoteServiceAdapter() {

	}

	public static RemoteServiceAdapter instance() {
		return new RemoteServiceAdapter();
	}

	// Login service.
	public String loginIn(String pAccount, String pPassword) {
		LoginVO vo = new LoginVO(pAccount, pPassword);
		String identity = null;
		try {
			identity = Stub.getService().loginIn(vo);
			if (identity == null) return null;
			
			if (identity.equals(LogicConstants.ADMIN)) {
				return AdminNavigater.class.getSimpleName();
			} 
			if (identity.equals(LogicConstants.CUSTOMER)) {
				return CustomerNavigater.class.getSimpleName();
			}
			if (identity.equals(LogicConstants.GENERAL_MANAGER)) {
				return GeneralManagerNavigater.class.getSimpleName();
			}
			if (identity.equals(LogicConstants.MARKET_MANAGER)) {
				return MarketManagerNavigater.class.getSimpleName();
			}
		} catch (RemoteException e) {
			identity = "";
		}
		return identity;
	}

	public boolean register(RegisterPanel.InvolvedData data) {
        RegisterVO registerVO = new RegisterVO();
        registerVO.update(data.mAccount, data.mPassword, data.mName, data.mPhone, data.mAddress);
        boolean isSuccess = false;
        try {
			isSuccess = Stub.getService().register(registerVO);
		} catch (RemoteException e) {
			// Do nothing.
		}
		return isSuccess;
	}
	
	
	// Customer service : book search.
	public String[] getBookSorts() {
		String[] sorts = new String[0];
		try {
			sorts = Stub.getService().showCategroy();
		} catch (RemoteException e) {
			e.printStackTrace();
		}
		return sorts;
	}
	
	public CustomerHomePage.InvolvedData[] showSearchedBook(String pSort,
			String pKeyword) {
		CustomerHomePage.InvolvedData[] datas = null;
		try {
			Book[] books = Stub.getService().showSearchedBook(pSort, pKeyword);
			datas = new CustomerHomePage.InvolvedData[books.length];
			for (int i = 0; i < books.length; i++) {
				Book book = books[i];
				datas[i] = new CustomerHomePage.InvolvedData();
				datas[i].mImage = ImageCoding.imageEncode(book.image);
				datas[i].mAuthor = book.author;
				datas[i].mDescription = book.description;
				datas[i].mName = book.name;
				datas[i].mPress = book.press;
				datas[i].mPrice = book.price + "";
				datas[i].mId = book.id;
				datas[i].mStorage = book.num;
			}
		} catch (RemoteException e) {
			e.printStackTrace();
		}
		return datas;
	}

	// Customer service : personal info manage.
	public PersonalInfoPage.InvolvedData showCustomerInfo(String pKey) {
		PersonalInfoPage.InvolvedData data = new PersonalInfoPage.InvolvedData();
		try {
			CustomerVO customerVO = Stub.getService().showCustomerInfo(pKey);
			data.name = customerVO.mName;
			data.password = customerVO.mPassword;
			data.phone = customerVO.mCellNumber;
			data.credits = customerVO.mCreditPoints + "";
			data.couponses = customerVO.getCoupons();
			data.address = customerVO.mAddress;
		} catch (RemoteException e) {
			e.printStackTrace();
		}
		return data;
	}
	
	public void modifyCustomerInfo(String pAccount,PersonalInfoPage.InvolvedData mData) {
		CustomerVO iVo=new CustomerVO();
		iVo.mAccount=pAccount;
		iVo.mPassword=mData.password;
		iVo.mName=mData.name;
		iVo.mAddress=mData.address;
		iVo.mCellNumber=mData.phone;
		iVo.mCreditPoints=Double.parseDouble(mData.credits);
		try {
			Stub.getService().modifyCustomerInfo(iVo);
		} catch (RemoteException e) {
			e.printStackTrace();
		}
	}
	
	// Customer service : collection manage.
	public CollectionPage.InvolvedData[] showCollection(String pKey) {
		CollectionPage.InvolvedData[] datas = null;
		try {
			Book[] books = Stub.getService().showCollection(pKey);
			datas = new CollectionPage.InvolvedData[books.length];
			for (int i = 0; i < books.length; i++) {
				datas[i] = new CollectionPage.InvolvedData();
				datas[i].publishDate = DateTransfer.formateDate(books[i].publishDate);
				datas[i].image = ImageCoding.imageEncode(books[i].image);
				datas[i].author = books[i].author;
				datas[i].description = books[i].description;
				datas[i].name = books[i].name;
				datas[i].press = books[i].press;
				datas[i].price = books[i].price + "";
				datas[i].id = books[i].id;
			}
		} catch (RemoteException e) {

		}
		return datas;
	}
	
	public boolean collectBook(String pUserId,String pBookId) {
		boolean result = false;
		try {
			result = Stub.getService().collectBook(pUserId, pBookId);
		} catch (RemoteException e) {
			e.printStackTrace();
		}
		return result;
	}

	public boolean unCollectBook(String pUserId,String pBookId) {
		boolean result = false;
		try {
			result = Stub.getService().unCollectBook(pUserId, pBookId);
		} catch (RemoteException e) {
			e.printStackTrace();
		}
		return result;
	}

	// Customer service : cart manage.
	public CartPage.InvolvedData[] showCartInfo() {
		String[] ids = sCartBuf.getBookIds();
		CartPage.InvolvedData[] datas = null;
		try {
			Book[] books = Stub.getService().showCartInfo(ids);
			datas = new CartPage.InvolvedData[ids.length];
			for (int i = 0; i < datas.length; i++) {
				Book book = books[i];
				datas[i] = new CartPage.InvolvedData();
				datas[i].mAuthor = book.author;
				datas[i].mIcon = ImageCoding.imageEncode(books[i].image);
				datas[i].mName = book.name;
				datas[i].mPrice = book.price;
				datas[i].mSort = book.category;
				datas[i].mAmount = book.num;
				datas[i].mId = book.id;
			}
		} catch (RemoteException e) {
			e.printStackTrace();
		}
		return datas;
	}

	public EndBillPanel.InvolvedData getCoupons(String account) {
		EndBillPanel.InvolvedData data = new EndBillPanel.InvolvedData();
		data.mCoupons = showCustomerInfo(account).couponses;
		data.mMaxEqualUse = getPromotionInfo().mMaxUseCount;
		return data;
	}

	// Customer service : order manage.
	public OrderPage.InvolvedData[] showCustomerOrder(String pKey,int pPage) {
		int begin = pPage * UIConstants.MAX_VISIBLE_COUNT;
		int end = (pPage + 1) * UIConstants.MAX_VISIBLE_COUNT - 1;
		OrderPage.InvolvedData[] datas = null;
		try {
			OrdersVO ordersVO = Stub.getService().showCustomerOrder(pKey, begin, end);
			OrderVO[] orderVOs = ordersVO.getOrderVO();
			ArrayList<OrderPage.InvolvedData> list = new ArrayList<OrderPage.InvolvedData>();
			for (int i = 0; i < orderVOs.length && orderVOs[i] != null; i++) {
				Order order = orderVOs[i].getOrder();
				OrderPage.InvolvedData data = new OrderPage.InvolvedData();
				data.mDate = DateTransfer.formateDate(order.mDate);
				data.mOrderId = order.mId;
				data.mPrice = order.allPrice + "";
				data.mState = order.getState();
				data.mBook = orderVOs[i].booksToString();
				list.add(data);
			}
			datas = new OrderPage.InvolvedData[list.size()];
			return list.toArray(datas);
		} catch (RemoteException e) {
			e.printStackTrace();
		}

		return new OrderPage.InvolvedData[0];
	}

	// General manager : promotion strategy manage. 
	public PromotionSettingPage.InvolvedData getPromotionInfo() {
		PromotionSettingPage.InvolvedData data = new PromotionSettingPage.InvolvedData();
		try {
			PromotionConfigVO promotionConfigVO = Stub.getService().showPromotionConfig();
			data.mAvailabelCredit = promotionConfigVO.mRule;
			data.mDiscoutValue = promotionConfigVO.mDiscountRate;
			data.mEqualValue = (int) promotionConfigVO.mEqualValue;
			data.mMaxUseCount = promotionConfigVO.mEqualMaxuseCount;
		} catch (RemoteException e) {
			e.printStackTrace();
		}
		return data;
	}

	public boolean setPromotionInfo(PromotionSettingPage.InvolvedData pData) {
		PromotionConfigVO promotionConfigVO = new PromotionConfigVO();
		promotionConfigVO.update(pData.mDiscoutValue, pData.mEqualValue, pData.mMaxUseCount, pData.mAvailabelCredit);
		try {
			Stub.getService().setPromotionInfo(promotionConfigVO);
			return true;
		} catch (RemoteException e) {
			return false;
		}
	}

	// General manager : promotion items manage. 
	public SendCouponsPage.InvolvedData[] showPromotionItems(int mCurrentPage) {
		int begin = mCurrentPage * UIConstants.MAX_VISIBEL_TABLE_COUNT;
		int end = (mCurrentPage + 1) * UIConstants.MAX_VISIBEL_TABLE_COUNT - 1;
		try {
			PromotionItemVO promotionItemVO= Stub.getService().showPromotionItems(begin,end);
			PromotionItem[] items=promotionItemVO.getPromotionItems();
			ArrayList<SendCouponsPage.InvolvedData> list = new ArrayList<SendCouponsPage.InvolvedData>();
			for (int i = 0; i < items.length && items[i] != null; i++) {
				SendCouponsPage.InvolvedData data = new SendCouponsPage.InvolvedData();
				data.mId = items[i].mID;
				data.mDate = items[i].mDate;
				data.mMinLevelCredits = items[i].mCreditsMin;
				data.mMaxLevelCredits = items[i].mCreditsMax;
				data.mDiscountCoupons = items[i].mDiscountCoupons.mCount;
				data.mEqualCoupons = items[i].mEqualCoupons.mCount;
				list.add(data);
			}
			SendCouponsPage.InvolvedData[] datas =new SendCouponsPage.InvolvedData[list.size()];
			list.toArray(datas);
			return datas;
		} catch (RemoteException e) {
		
		}
		return null;
	}

	public void addPromotionItem(SendCouponsPage.InvolvedData pData) {
		EqualCoupons equal = new EqualCoupons();
		equal.mCount = pData.mEqualCoupons;
		DiscountCoupons discount = new DiscountCoupons();
		discount.mCount = pData.mDiscountCoupons;
		PromotionItem addItem = new PromotionItem(pData.mId, pData.mDate,
												pData.mMinLevelCredits, pData.mMaxLevelCredits,discount, equal);
		try {
			Stub.getService().addPromotionItem(addItem);
		} catch (RemoteException e) {
			e.printStackTrace();
		}
	}

	public void removePromotionItem(String pKey) {
		try {
			Stub.getService().removePromotionItem(pKey);
		} catch (RemoteException e) {
			e.printStackTrace();
		}
	}

	// Market manager : customer manage.
	public InvolvedData[] showCustomerInfos(int mCurrentPage) {
		int begin = mCurrentPage * UIConstants.MAX_VISIBEL_TABLE_COUNT;
		int end = (mCurrentPage + 1) * UIConstants.MAX_VISIBEL_TABLE_COUNT - 1;
		CustomerVO[] customerVOs = null;
		try {
			customerVOs = Stub.getService().showCustomerInfos(begin, end);
		} catch (RemoteException e) {
			return null;
		}
		CustomerManagePage.InvolvedData[] datas = new CustomerManagePage.InvolvedData[customerVOs.length];
		for(int i = 0;i < customerVOs.length;++i){
			datas[i] = new CustomerManagePage.InvolvedData();
			datas[i].mAccount = customerVOs[i].mAccount;
			datas[i].mCredits = customerVOs[i].mCreditPoints;
			double[] coupons = customerVOs[i].getCoupons();
			datas[i].mEqualCoupons = SaleLogic.filterToEqual(coupons);
			datas[i].mDiscountCoupons = SaleLogic.filterToDiscount(coupons);
		}
		return datas;
	}
	
	public void sendCoupons(String pAccount, int pEqualCount, int pDiscountCount) {
		SendCouponVO sendCouponVO = new SendCouponVO();
		sendCouponVO.update(pAccount, pEqualCount, pDiscountCount);
		try {
			Stub.getService().sendCoupons(sendCouponVO);
		} catch (RemoteException e) {
			e.printStackTrace();
		}
	}
	
	// Market manager : order manage.
	public OrderManagePage.InvolvedData[] showCustomerOrders(int mCurrentPage) {
		int begin = mCurrentPage * UIConstants.MAX_VISIBLE_COUNT;
		int end = (mCurrentPage + 1) * UIConstants.MAX_VISIBLE_COUNT - 1;
		try {
			OrderVO[] orderVOs = Stub.getService().showCustomerOrders(begin, end).getOrderVO();
			OrderManagePage.InvolvedData[] datas=new OrderManagePage.InvolvedData[orderVOs.length];
			for (int i = 0; i < orderVOs.length; i++) {
				datas[i] = new OrderManagePage.InvolvedData();
				datas[i].mAddress=((CustomerInfo)orderVOs[i].getOrder().mUser.iUserInfo).mAddress;
				datas[i].mBook=orderVOs[i].booksToString();
				datas[i].mDate=DateTransfer.formateDate(orderVOs[i].getOrder().mDate);
				datas[i].mName=((CustomerInfo)orderVOs[i].getOrder().mUser.iUserInfo).mName;
				datas[i].mOrderId=orderVOs[i].getOrder().mId;
				datas[i].mPhone=((CustomerInfo)orderVOs[i].getOrder().mUser.iUserInfo).mCellNumber;
				datas[i].mPrice=orderVOs[i].getOrder().allPrice+"";
				datas[i].mState=orderVOs[i].getOrder().getState();
			}
			return datas;
		} catch (RemoteException e) {
			e.printStackTrace();
		}
		return new OrderManagePage.InvolvedData[0];
	}
	
	public boolean changeOrderState(String mOderId, String pState) {
		OrderState mState = null;
		if (pState.equals(LogicConstants.ORDER_STATES[LogicConstants.INDEX_CONFIRM])) {
			mState = OrderState.CONFIRM;
		}else if (pState.equals(LogicConstants.ORDER_STATES[LogicConstants.INDEX_DISBUTE])){
			mState = OrderState.DISTRIBUTE;
		}else if (pState.equals(LogicConstants.ORDER_STATES[LogicConstants.INDEX_SEND])){
			mState = OrderState.SEND;
		}else if (pState.equals(LogicConstants.ORDER_STATES[LogicConstants.INDEX_RECEIVED])){
			mState = OrderState.RECEIVED;
		}
		if (mState == null) return false;
		try {
			Stub.getService().changeOrderState(mOderId,mState);
			return true;
		} catch (RemoteException e) {
			return false;
		}
	}

	// Market manager : Book manage.
	public BookManagePage.InvolvedData[] showBooks(int mCurrentPage) {
		int begin = mCurrentPage * UIConstants.MAX_VISIBEL_TABLE_COUNT;
		int end = (mCurrentPage + 1) * UIConstants.MAX_VISIBEL_TABLE_COUNT - 1;
		BookManagePage.InvolvedData[] datas = null;
		try {
			Book[] books = Stub.getService().showBooks(begin,end);
			datas = new BookManagePage.InvolvedData[books.length];
			for (int i = 0; i < books.length; i++) {
				Book book = books[i];
				datas[i] = new BookManagePage.InvolvedData();
				datas[i].mIcon = ImageCoding.imageEncode(book.image);
				datas[i].mBookid= book.id;
				datas[i].mIsbn = book.ISBN;
				datas[i].mName= book.name;
				datas[i].mAuthor= book.author;
				datas[i].mPress= book.press;
				datas[i].mPublishDate= book.publishDate;
				datas[i].mCategory = book.category;
				datas[i].mPrice = book.price;
				datas[i].mDesciption = book.description;
				datas[i].mStorage= book.num;
			}
		} catch (RemoteException e) {
			e.printStackTrace();
		}
		return datas;
	}
	
	public boolean addBook(BookManagePage.InvolvedData pData)  {
		Book book=new Book(pData.mBookid, 
				           pData.mName, 
				           pData.mAuthor,
				           pData.mPress,
				           pData.mIsbn,
				           pData.mCategory, 
				           pData.mPublishDate, 
				           pData.mPrice,
				           pData.mDesciption, 
				           pData.mStorage,
				           pData.mIcon.getImageData());
		try {
			return Stub.getService().addBook(book);
		} catch (RemoteException e) {
			e.printStackTrace();
		}
		return false;
	}
	
	public void removeBook(String bookId) {
		try {
			Stub.getService().removeBook(bookId);
		} catch (RemoteException e) {
			e.printStackTrace();
		}
	}
	
	public boolean modifyBook(BookManagePage.InvolvedData pData) {
		Book book=new Book(pData.mBookid,
						   pData.mName,
						   pData.mAuthor, 
						   pData.mPress, 
						   pData.mIsbn,
						   pData.mCategory,
						   pData.mPublishDate, 
						   pData.mPrice,
				 	 	   pData.mDesciption, 
				 		   pData.mStorage, 
						   pData.mIcon.getImageData());
		try {
			return Stub.getService().modifyBook(book);
		} catch (RemoteException e) {
			return false;
		}
	}

	// Market manager : Book category manage.
	public void setCategory(String pOriginalcategory, String pNewcategory) {
		try {
			Stub.getService().setCatagry(pOriginalcategory, pNewcategory);
		} catch (RemoteException e) {
			e.printStackTrace();
		}
	}

	public boolean addCategory(String newSort) {
		try {
			return Stub.getService().addCategory(newSort);
		} catch (RemoteException e) {
			e.printStackTrace();
		}
		return false;
	}	
	
	public void removeCatogry(String sort) {
		try {
			Stub.getService().removeCategory(sort);
		} catch (RemoteException e) {
			e.printStackTrace();
		}
	}
	
	// Administrator manager : user manage.
	public AdminHomePage.InvolvedData[] showUser(int pPage, String pIdentity) {
		int begin = pPage * UIConstants.MAX_VISIBEL_TABLE_COUNT;
		int end = (pPage + 1) * UIConstants.MAX_VISIBEL_TABLE_COUNT - 1;
		 AdminHomePage.InvolvedData[] datas = null;
		try {
		 UserVO userVO = Stub.getService().showUser(begin, end,recognize(pIdentity));
	     datas = new AdminHomePage.InvolvedData[userVO.getUsers().length];
		 for (int i = 0; i < datas.length; i++) {
			datas[i] = new AdminHomePage.InvolvedData();
			datas[i].mAccount = userVO.getUsers()[i].iAccount;
			datas[i].mPassword = userVO.getUsers()[i].iPassword;
			datas[i].mIdentity = userVO.getUsers()[i].getIdentity();
		}
		} catch (RemoteException e) {
			e.printStackTrace();
		}
		return datas;
	}

	public boolean removeUsers(String pAccount) {
		try {
			return Stub.getService().removeUsers(pAccount);
		} catch (RemoteException e) {
			e.printStackTrace();
		}
		return false;
	}

	public boolean addUser(String pAccount, String pPassword, String pIdentity) {
          try {
			return Stub.getService().add(pAccount, pPassword, pIdentity);
		} catch (RemoteException e) {
			e.printStackTrace();
		}
        return false;
	}

	public void modifyUser(String pAccount, String pPassword) {
		try {
			Stub.getService().modifyUser(pAccount, pPassword);
		} catch (RemoteException e) {
			e.printStackTrace();
		}
	}
	
	public double purchase(String pAccount, String[] pBookIds, int[] pCounts, double pAllPrice, double[] right) {
		EqualCoupons[] equalCoupons = null;
		double discountCoupons = 0;
		if (right.length > 0) {
			boolean isDiscount = right[0] < 1;
			if (isDiscount) {
				discountCoupons = right[0];
			} else {
				equalCoupons = SaleLogic.merge(right);
			}
		}
		SaleVO salevo = new SaleVO();
		salevo.update(pAccount,pBookIds, pCounts, equalCoupons, discountCoupons, pAllPrice);
		double credit = 0.0;
		try {
			credit = Stub.getService().purchase(salevo);
		} catch (RemoteException e) {
			// DO-NOTHING.
		}
		
		return credit;
	}

	private UserIdentity recognize(String pIdentity){
		 UserIdentity iIdentity=UserIdentity.UNKONWN;
         if (pIdentity.equals(LogicConstants.ADMIN)){
       	  iIdentity=UserIdentity.ADMIN;
         }else if (pIdentity.equals(LogicConstants.CUSTOMER)){
       	  iIdentity=UserIdentity.CUSTOMER;
         }else if (pIdentity.equals(LogicConstants.GENERAL_MANAGER)){
       	  iIdentity=UserIdentity.GENERAL_MANAGER;
         }else if (pIdentity.equals(LogicConstants.MARKET_MANAGER)){
       	  iIdentity=UserIdentity.SALES_MANAGER;
         }
         return iIdentity;
	}
}
